package #(table.packageName).controller;

import #(table.packageName).domain.#(table.name);
#if(option.isGenFormVo())
import #(table.packageName).domain.#(table.name)Vo;
#end

import lombok.RequiredArgsConstructor;

import com.rankeiot.core.anno.Auth;
import com.rankeiot.core.inner.argumet.QueryPage;
import com.rankeiot.core.inner.argumet.QueryParams;
import com.rankeiot.core.util.CollectionUtil;
import org.sagacity.sqltoy.dao.LightDao;
import org.sagacity.sqltoy.model.Page;
import com.rankeiot.core.data.response.Resp;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
#if(option.isGenExport())
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
import org.springframework.http.ResponseEntity;
import com.rankeiot.core.excel.ExcelBatchImporter;
import com.rankeiot.core.excel.ExcelStreamExporter;
import org.sagacity.sqltoy.model.QueryExecutor;
import java.util.Date;
import java.io.IOException;
import cn.hutool.core.date.DateUtil;

#end
#if(option.isGenPriv())
import #(table.packageName).#(firstToUpperCase(table.module))Menu;
#end
#if(!option.isGenMapper())
import com.rankeiot.core.sqltoy.Sql;
#end


import jakarta.validation.Valid;
import java.util.List;
import java.util.Map;

/**
* #(table.title)
*/
@Tag(name="#(table.title)")
@Auth
@RestController
@RequestMapping("#(firstToLowerCase(table.name))")
@RequiredArgsConstructor
public class #(table.name)Controller{

    final LightDao dao;

    /**
    * 新增#(table.title)
    */
    @Operation(summary="新增#(table.title)")
    #if(option.isGenPriv())
    @Auth(#(firstToUpperCase(table.module))Menu.#(table.name.toUpperCase())_ADD)
    #end
    @PostMapping("add")
    public Resp add(@Valid @RequestBody #(table.name) #(firstToLowerCase(table.name))){
        dao.save(#(firstToLowerCase(table.name)));
        return Resp.ok();
    }

    /**
    * 删除#(table.title)
    */
    @Operation(summary="删除#(table.title)")
    #if(option.isGenPriv())
    @Auth(#(firstToUpperCase(table.module))Menu.#(table.name.toUpperCase())_DELETE)
    #end
    @Transactional
    @PostMapping("delete")
    public Resp delete(List<#(table.firstPk().dataType)> #(table.firstPk().field)s){
        // dao.loadAll(#(firstToLowerCase(table.name))s);
        List<#(table.name)> #(firstToLowerCase(table.name))s = CollectionUtil.map(#(table.firstPk().field)s,#(table.name)::new);
        dao.deleteAll(#(firstToLowerCase(table.name))s);
        return Resp.ok();
    }

    /**
    * 更新#(table.title)
    */
    @Operation(summary="更新#(table.title)")
    #if(option.isGenPriv())
    @Auth(#(firstToUpperCase(table.module))Menu.#(table.name.toUpperCase())_EDIT)
    #end
    @PostMapping("save")
    public Resp save(@Valid @RequestBody #(table.name) #(firstToLowerCase(table.name))){
        dao.update(#(firstToLowerCase(table.name)));
        return Resp.ok();
    }

    /**
    *  获取#(table.title)
    */
    @Operation(summary="获取#(table.title)详细")
    #if(option.isGenPriv())
    @Auth(#(firstToUpperCase(table.module))Menu.#(table.name.toUpperCase()))
    #end
    @GetMapping("detail")
    public Resp<#(table.name)> detail(#(table.pkArgs())){
       #(table.name) #(firstToLowerCase(table.name))=dao.load(new #(table.name)(#(table.getPks())));
       return Resp.of(#(firstToLowerCase(table.name)));
    }
    /**
    * 获取#(table.title)列表
    */
    @Operation(summary="列出#(table.title)")
    #if(option.isGenPriv())
    @Auth(#(firstToUpperCase(table.module))Menu.#(table.name.toUpperCase()))
    #end
    @PostMapping("list")
    public Resp<#(table.name)> list(QueryPage query){
        #if(option.isGenMapper())
        Page result = dao.findPage(query.page(),"#(firstToLowerCase(table.name))_list",query.params(),#(table.name).class);
        #else
        String sql=Sql.select("#(table.listFields)")
                .from(#(table.name).TABLE)
                #if(table.hasSearch()).optional(q -> q
#for(column:table.columns)#if(column.isSearchCondition())
                    .eq(#(table.name).Fields.#(column.field))
#end#end
                )#end.orderByDesc(#(table.name).Fields.#(table.firstPk().field))
                .toString();
        Page result = dao.findPage(query.page(),sql,query.params(),#(table.name).class);
        #end
        return Resp.of(result);
    }

    #if(option.isGenExport())
    /**
    * 导出#(table.title)
    */
    @Operation(summary="导出#(table.title)")
    #if(option.isGenPriv())
    @Auth(#(firstToUpperCase(table.module))Menu.#(table.name.toUpperCase()))
    #end
    @PostMapping(value="export",produces = "application/vnd.ms-excel")
    public ResponseEntity<StreamingResponseBody> export(QueryParams query){
        #if(option.isGenMapper())
        return Resp.export("#(table.title)" + DateUtil.format(new Date(), "yyMMdd") + ".xlsx"
                    , out -> {
                        ExcelStreamExporter exporter = new ExcelStreamExporter(out);
                        dao.fetchStream(query.getQueryExecutor("#(firstToLowerCase(table.name))_list").resultType(#(table.name)#if(option.isGenFormVo())Vo#end.class), exporter);
                    });
        #else
        String sql=Sql.select("#(table.listFields)")
                    .from(#(table.name).TABLE)
                    #if(table.hasSearch()).optional(q -> q
#for(column:table.columns)#if(column.isSearchCondition())
                        .eq(#(table.name).Fields.#(column.field))
#end#end
                    )#end.orderByDesc(#(table.name).Fields.#(table.firstPk().field))
                    .toString();
       return Resp.export("#(table.title)" + DateUtil.format(new Date(), "yyMMdd") + ".xlsx"
                    , out -> {
                        ExcelStreamExporter exporter = new ExcelStreamExporter(out);
                        dao.fetchStream(query.getQueryExecutor(sql).resultType(#(table.name)#if(option.isGenFormVo())Vo#end.class), exporter);
                    });
        #end
    }
    /**
    * 导入#(table.title)
    */
    @Operation(summary="导入#(table.title)")
    #if(option.isGenPriv())
    @Auth(#(firstToUpperCase(table.module))Menu.#(table.name.toUpperCase())_ADD)
    #end
    @Transactional
    @PostMapping("import")
    public Resp importData(MultipartFile file) throws IOException {
        if(file==null){
             Resp.fail("未上传文件");
        }
        ExcelBatchImporter importer=new ExcelBatchImporter(file.getInputStream(), #(table.name).class);
        importer.start((batchData,lastIndex)->{
            dao.saveAll(batchData);
        });
        return Resp.ok();
    }
    #end
}
